package com.bub.pay.framework.wrap.aspect;

import javax.servlet.http.HttpServletRequest;

import com.bub.pay.framework.common.util.IpRemote;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.bub.pay.framework.common.base.BaseVo;

@Aspect
@Component
public class RestLogAspect {

	private final Logger log = LoggerFactory.getLogger(RestLogAspect.class);

	private ThreadLocal<Long> startTime = new ThreadLocal<>();
	private ThreadLocal<String> method = new ThreadLocal<>();

	@Pointcut("execution(public * com.bub.pay.api.controller..*.*(..))")
	public void restLog() {
	}

	@Before("restLog()")
	public void doBefore(JoinPoint joinPoint) {

		startTime.set(System.currentTimeMillis());
		// 接收到请求，记录请求内容
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();

		// 记录下请求内容
		log.info("请求URL : " + request.getRequestURL().toString());
		log.info("IP&方式 : 【" + IpRemote.getIpAddr(request)+ "】【" + request.getMethod() + "】");
		log.info("请求方法: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
		method.set(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
		Object[] args = joinPoint.getArgs();
		for (Object obj : args) {
			 if (obj instanceof BaseVo) {
				SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
				log.info("请求参数 : " + JSON.toJSONString(obj,filter, SerializerFeature.WriteMapNullValue,
						SerializerFeature.WriteNullStringAsEmpty));
			}else if (obj instanceof String) {
				log.info("请求参数 : "+obj.toString());
			}else if (obj instanceof Integer) {
				log.info("请求参数 : "+obj.toString());
			}else if (obj instanceof Long) {
				log.info("请求参数 : "+obj.toString());
			}
		}
	}

	@AfterReturning(returning = "ret", pointcut = "restLog()")
	public void doAfterReturning(Object ret) throws Throwable {
		log.info("请求方法 : " + method.get() + "响应时间 : " + (System.currentTimeMillis() - startTime.get()));
	}
}
